package com.boot.proofing.common.config;/**
 * @description
 * @autor xbwu on 2018/1/22.
 */

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.alibaba.fastjson.support.config.FastJsonConfig;
import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter;
import com.boot.core.common.base.ResultWapper;
import com.boot.core.common.enums.ResultEnum;
import com.boot.proofing.common.util.WebUtils;
import com.boot.proofing.mpweb.base.entity.User;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.web.servlet.MultipartConfigFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.format.FormatterRegistry;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.InterceptorRegistration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import javax.servlet.MultipartConfigElement;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.List;

/**
 * 登录、跨域、枚举转换配置拦截--基于SpringMVC配置
 *
 * @author xbwu
 * @create 2018-01-22
 **/
@Configuration
public class WebSecurityConfig implements WebMvcConfigurer {

    public final Logger logger = LoggerFactory.getLogger(this.getClass());
    /**
     * 登录session key
     */
    public final static String USER = "user";

    @Bean
    public SecurityInterceptor getSecurityInterceptor() {
        return new SecurityInterceptor();
    }

    /**
     * 通用登录拦截配置
     *
     * @param registry
     */
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        InterceptorRegistration addInterceptor = registry.addInterceptor(getSecurityInterceptor());

        // 排除配置
        //登录相关
        addInterceptor.excludePathPatterns("/lg/**");
        //首页
        addInterceptor.excludePathPatterns("/");
        //静态资源相关
        addInterceptor.excludePathPatterns("/res/**");
        //定时任务
        addInterceptor.excludePathPatterns("/quartz/**");
        //客户采集接口
        addInterceptor.excludePathPatterns("/customer/**");
        //通用app直通接口
        addInterceptor.excludePathPatterns("/app/**");
        // 拦截配置
        addInterceptor.addPathPatterns("/**");
    }

    /**
     * 登录拦截
     */
    private class SecurityInterceptor extends HandlerInterceptorAdapter {

        @Override
        public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
            HttpSession session = request.getSession();
            if (session.getAttribute(USER) != null) {
                //先移除后添加，避免被线程池影响
                WebUtils.unbindUser();
                WebUtils.bindUser((User) session.getAttribute(USER));
                return true;
            }
            // 跳转登录
//            String url = "/login";
//            response.sendRedirect(request.getContextPath()+url);
            returnJson(response, JSON.toJSONString(ResultWapper.error("当前未登录", ResultEnum.NOT_LOGIN)));
            return false;
        }
        private void returnJson(HttpServletResponse response, String json){
            PrintWriter writer = null;
            response.setCharacterEncoding("UTF-8");
            response.setContentType("application/json; charset=utf-8");
            try {
                writer = response.getWriter();
                writer.print(json);

            } catch (IOException e) {
                logger.error("nologin response error", e);
            } finally {
                if (writer != null){ writer.close();}
            }
        }
    }

    /**
     * 跨域CORS配置
     *
     * @param registry
     */
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        //允许任何访问路径
        registry.addMapping("/**")
                //允许任何请求头
                .allowedHeaders("*")
                //只允许post和get方法
                .allowedMethods("POST", "GET")
                //允许任何域名使用
                .allowedOrigins("*");
    }

    /**
     * <p>
     * 消息转换，避免js Long精度丢失
     * </p>
     */
    @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
        FastJsonHttpMessageConverter fastJsonConverter = new FastJsonHttpMessageConverter();
        FastJsonConfig fjc = new FastJsonConfig();
        //1、序列化重点
        fjc.setSerializerFeatures(SerializerFeature.BrowserCompatible);
        fastJsonConverter.setFastJsonConfig(fjc);
        converters.add(fastJsonConverter);
    }

    /**
     * 添加枚举类转换器
     *
     * @param registry
     */
    @Override
    public void addFormatters(FormatterRegistry registry) {
        registry.addConverterFactory(new UniversalEnumConverterFactory());
    }

    /**
     * 上传文件控制
     *
     * @return
     */
    @Bean
    public MultipartConfigElement multipartConfigElement() {
        MultipartConfigFactory factory = new MultipartConfigFactory();
        //文件最大KB,MB
        factory.setMaxFileSize("2MB");
        //设置总上传数据总大小
        factory.setMaxRequestSize("10MB");
        return factory.createMultipartConfig();
    }
}
